package com.situ.util;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import javax.sql.DataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;

public class DBUtil {

	private static DataSource dataSource;

	static {
		try {

			Properties ps = new Properties();
			ps.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties"));
			dataSource = DruidDataSourceFactory.createDataSource(ps);

		} catch (Exception e) {

			System.out.println("初始化数据库连接池失败");
			e.printStackTrace();

		}
	}

	public static <T> List<T> executeDQL(String sql, Class<T> c, Object... params) {
		List<T> list = new ArrayList<>();
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			conn = getConnection();
			ps = conn.prepareStatement(sql);
			if (params != null) {
				for (int i = 0; i < params.length; i++) {
					ps.setObject(i + 1, params[i]);
				}
			}
			rs = ps.executeQuery();
			ResultSetMetaData rsmd = rs.getMetaData();// 原数据

			while (rs.next()) {
				T obj = c.newInstance();
				// i表示第几列
				for (int i = 1; i <= rsmd.getColumnCount(); i++) {
					Object value = rs.getObject(i);// 第i列的值
					String label = rsmd.getColumnLabel(i);// 获取第i列的表头名

					try {
						Field field = c.getDeclaredField(StringUtil.underLineToHump(label));// 找到根表头名重名的成员变量
						field.setAccessible(true);// 改权限
						field.set(obj, value);// 赋值
					} catch (Exception e) {
						System.out.println(label + ":这一列没找到!");
					}

				}
				list.add(obj);

			}
		} catch (Exception e) {
			System.out.println("查询失败！");
			e.printStackTrace();
		} finally {
			DBUtil.close(rs, ps, conn);
		}
		return list;
	}

	public static int executeDML(String sql, Object... params) {
		Connection conn = null;
		PreparedStatement ps = null;
		try {
			conn = getConnection();
			ps = conn.prepareStatement(sql);
			if (params != null) {
				for (int i = 0; i < params.length; i++) {
					ps.setObject(i + 1, params[i]);
				}
			}
			return ps.executeUpdate();
		} catch (Exception e) {
			System.out.println(e);
			try {
				conn.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}

		} finally {
			DBUtil.close(ps, conn);
		}
		return 0;
	}

	public static Connection getConnection() throws SQLException {

		return dataSource.getConnection();

	}

	public static Long executeCount(String sql, Object... params) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			conn = getConnection();
			ps = conn.prepareStatement(sql);
			if (params != null) {
				for (int i = 0; i < params.length; i++) {
					ps.setObject(i + 1, params[i]);
				}
			}
			rs = ps.executeQuery();
			rs.next();

			return rs.getLong(1);

		} catch (Exception e) {
			return 0L;
		} finally {
			DBUtil.close(rs, ps, conn);
		}
		
	}

	// 用于释放资源rs,ps,coon
	public static void close(ResultSet rs, PreparedStatement ps, Connection conn) {
		if (rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if (ps != null) {
			try {
				ps.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	// 用于释放资源ps,coon
	public static void close(PreparedStatement ps, Connection conn) {

		close(null, ps, conn);
	}
}
